package com.oa.demo.auth.config;

import com.oa.demo.auth.filter.ValidateCodeFilter;
import com.oa.demo.auth.service.impl.UserDetailServiceIml;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * 安全配置适配器
 * security安全配置器,用于登录校验和权限的初始化. 默认order100,资源配置的order是3,设置Order(2)在资源适配器之前起作用
 * 作用:
 *      过滤oauth/**的接口,校验客户端,获取刷新token,登录校验,权限的初始化
 *
 *
 * @author 孔德成
 * @date 2020/11/20 15:15
 */
@Order(2)
@Configuration
@EnableWebSecurity
public class OaWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {


    @Autowired
    private UserDetailServiceIml userDetailServiceIml;

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private ValidateCodeFilter validateCodeFilter;

    /**
     * 认证管理器
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    /**
     * 身份验证管理器生成器
     *      需要配置userDetail获取实现和秘密的加密规则
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailServiceIml).passwordEncoder(passwordEncoder);
    }

//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }

    /**
     * 可以在此处指定需要防御常见漏洞的任何端点，包括公共漏洞
     * @param http 与名称空间配置中的Spring Security的XML <http>元素相似。 它允许为特定的http请求配置基于Web的安全性。 默认情况下，它将应用于所有请求
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //将验证码过滤器放到密码校验器之前
        http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
        .requestMatchers()
                .antMatchers("/oauth/**")
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated()
                .and()
                .csrf().disable();

    }
}
